package com.heima.account.service.impl;


import com.heima.account.entity.AccountFreeze;
import com.heima.account.mapper.AccountFreezeMapper;
import com.heima.account.mapper.AccountMapper;
import com.heima.account.service.AccountTCCService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class AccountTCCServiceImpl implements AccountTCCService {
    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private AccountFreezeMapper freezeMapper;


    @Override
    public void deduct(Integer userId, Integer money) {
        // 0.获取事务id
        String xid = RootContext.getXID();
        // 解决业务悬挂
        AccountFreeze oldFreeze = freezeMapper.selectById(xid);
        if (oldFreeze != null) {
            return;
        }
        //1. 扣除可用余额
        accountMapper.deduct(userId, money);
        //2. 记录冻结金额，事务状态
        AccountFreeze freeze = new AccountFreeze();
        freeze.setXid(xid);
        freeze.setUserId(userId);
        freeze.setFreezeMoney(money);
        freeze.setState(AccountFreeze.State.TRY);
        freezeMapper.insert(freeze);
    }

    @Override
    public Boolean confirm(BusinessActionContext ctx) {
        //1. 获取xid
        String xid = ctx.getXid();
        //2.删除冻结记录
        int count = freezeMapper.deleteById(xid);
        return count == 1;
    }

    @Override
    @Transactional
    public Boolean cancel(BusinessActionContext ctx) {
        //1. 查询冻结记录
        String xid = ctx.getXid();
        AccountFreeze freeze = freezeMapper.selectById(xid);

        //解决空回滚
        if(freeze == null){
            int userId = Integer.parseInt(ctx.getActionContext("userId").toString());
            freeze=new AccountFreeze();
            freeze.setXid(xid);
            freeze.setUserId(userId);
            freeze.setFreezeMoney(0);
            freeze.setState(AccountFreeze.State.CACEL);
            freezeMapper.insert(freeze);
            return true;
        }


        //解决幂等性
        if(freeze.getState() == AccountFreeze.State.CACEL){
            return true;
        }
        //2. 回复账户金额
        accountMapper.refund(freeze.getUserId(),freeze.getFreezeMoney());
        //3.更新冻结记录
        freeze.setFreezeMoney(0);
        freeze.setState(AccountFreeze.State.CACEL);
        int count = freezeMapper.updateById(freeze);
        return count==1;
    }
}
